<template>
  <div class="setting-main">
    <div v-if="fieldItems && fieldItems.length" class="setting-list">
      <div v-loading="addLoading" class="tree-content">
        <el-tree
          :data="fieldItems"
          :props="defaultProps"
          :default-expanded-keys="defaultExpandedKeys"
          :expand-on-click-node="true"
          :draggable="draggable"
          :allow-drop="allowDrop"
          :allow-drag="allowDrag"
          node-key="pid"
          @node-drag-start="handleDragStart"
          @node-drag-enter="handleDragEnter"
          @node-drag-leave="handleDragLeave"
          @node-drag-over="handleDragOver"
          @node-drag-end="handleDragEnd"
          @node-drop="handleDrop">
          <div slot-scope="{ node, data }" class="custom-tree-node">
            <div class="expend-btn">
              <img v-if="!node.isLeaf && !node.expanded" :src="expend" class="expend-icon" alt="">
              <img v-if="!node.isLeaf && node.expanded" :src="expend_active" class="expend-icon" alt="">
              <img v-if="node.isLeaf" :src="expend_active_no" class="expend-icon" alt="">
            </div>
            <div v-if="!data._isEdit && !data._isAdd" :class="node.isLeaf && allowDrag && allowDrag(node) && 'is-draggable'" class="tree-main">
              <!-- 客户状态独有 -->
              <template v-if="isCustomerStatus(node)">
                <span :style="{color: data.color || '#333', background: data.color ? changeColorAlphaVal(data.color, 0.14) : 'transparent'}" class="customer-status-label">{{ node.label }}</span>
              </template>
              <template v-else>
                <div class="flex-center">
                  <div>{{ node.label }}<span v-if="data.originalName">（原字段名称：{{ data.originalName }}）</span></div>
                  <el-switch
                    v-if="statusRequired && (!data._isAdd || !data._isEdit) && (node.level === 3 || node.parent.data.id === 24)"
                    v-model="data.status"
                    :active-value="true"
                    :inactive-value="false"
                    disabled
                    active-color="#406EFF"
                    inactive-color="#ccc"
                    active-text="启用"
                    inactive-text="禁用"
                    style="margin-left: 16px;"
                    class="nopointer"/>
                </div>
              </template>
            </div>
            <!-- 新增/编辑 -->
            <div class="tree-main" @click.prevent.stop="() => {}">
              <!-- 编辑 -->
              <template v-if="(!data.fieldSetting || (data.fieldSetting && (data.level === 3 || data.level === 4))) && data._isEdit && !data._isAdd">
                <div v-if="data.fieldSetting && data.level === 4" class="select-type">
                  <el-select v-model="data.platformId" size="small" placeholder="请选择下单平台">
                    <el-option v-for="item in platformList" :key="item.id" :label="item.value" :value="item.id"/>
                  </el-select>
                  <div class="input-btn" style="margin-left: 10px;">
                    <i class="el-icon-check" @click.stop="httpEditSetting(node,data)" />
                    <i class="el-icon-close" @click.stop="toEditSetting(node, data)" />
                  </div>
                </div>
                <div v-else-if="showSelectType && node.isLeaf" class="select-type">
                  <el-input v-model="data.editName" :maxlength="50" size="small" class="input width140" placeholder="请输入内容" />
                  <el-select v-model="data.editOptionsType" size="small" class="width140" placeholder="请选择类型">
                    <el-option v-for="item in optionsTypeList" :key="item.value" :label="item.label" :value="item.value"/>
                  </el-select>
                  <div class="input-btn" style="margin-left: 10px;">
                    <i class="el-icon-check" @click.stop="httpEditSetting(node,data)" />
                    <i class="el-icon-close" @click.stop="toEditSetting('', data, false)" />
                  </div>
                </div>
                <el-input v-else v-model="data.editName" :maxlength="50" size="small" class="input" placeholder="请输入内容" >
                  <div slot="suffix" class="el-input__icon">
                    <i class="el-icon-check" @click.stop="httpEditSetting(node,data)" />
                    <i class="el-icon-close" @click.stop="toEditSetting('', data, false)" />
                  </div>
                </el-input>
                <!-- 客户状态独有 -->
                <el-color-picker
                  v-if="isCustomerStatus(node)"
                  v-model="data.color"
                  show-alpha
                  color-format="rgb"
                  size="small"
                  style="position: absolute"/>
              </template>
              <!-- 新增 -->
              <template v-if="data._isAdd && !data._isEdit">
                <div v-if="data.fieldSetting && data.level === 4" class="select-type">
                  <el-select v-model="data.platformId" size="small" placeholder="请选择下单平台">
                    <el-option v-for="item in platformList" :key="item.id" :label="item.value" :value="item.id"/>
                  </el-select>
                  <div class="input-btn" style="margin-left: 10px;">
                    <i class="el-icon-check" @click.stop="httpAddSetting(node,data)" />
                    <i class="el-icon-close" @click.stop="cancelAdd(node, data)" />
                  </div>
                </div>
                <div v-else-if="showSelectType && data.showOptionsType" class="select-type">
                  <el-input v-model="data.name" :maxlength="50" size="small" class="input width140" placeholder="请输入内容" />
                  <el-select v-model="data.optionsType" size="small" class="width140" placeholder="请选择类型">
                    <el-option v-for="item in optionsTypeList" :key="item.value" :label="item.label" :value="item.value"/>
                  </el-select>
                  <div class="input-btn" style="margin-left: 10px;">
                    <i class="el-icon-check" @click.stop="httpAddSetting(node,data)" />
                    <i class="el-icon-close" @click.stop="cancelAdd(node, data)" />
                  </div>
                </div>
                <el-input v-else v-model="data.name" :maxlength="50" size="small" class="input" placeholder="请输入内容" >
                  <div slot="suffix" class="el-input__icon">
                    <i class="el-icon-check" @click.stop="httpAddSetting(node, data)" />
                    <i class="el-icon-close" @click.stop="cancelAdd(node, data)" />
                  </div>
                </el-input>
                <!-- 客户状态独有 -->
                <el-color-picker
                  v-if="isCustomerStatus(node)"
                  v-model="data.color"
                  show-alpha
                  color-format="rgb"
                  size="small"
                  style="position: absolute"/>
              </template>
              <!-- 附加选项 -->
              <el-select
                v-if="extentSelect && (!extentSelect.auth || extentSelect.auth(node, data))"
                v-model="data[extentSelect.key]"
                :style="!data._isAdd && !data._isEdit?{marginLeft: '12px'}:{ }"
                :placeholder="extentSelect.placeholder"
                multiple
                size="small"
                class="tag-module-select"
                collapse-tags
                clearable
                @change="extentSelectChange(node, data)">
                <el-option
                  v-for="item in extentSelect.list"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"/>
              </el-select>
            </div>
            <el-checkbox v-if="checkboxRequired && (data._isAdd || data._isEdit)" v-model="data.isRequired" style="margin-left: 16px;">{{ requiredText }}</el-checkbox>
            <el-checkbox v-if="lastCheckRequired && (data._isAdd || data._isEdit) && node.level === 3" v-model="data.isRequired" style="margin-left: 16px;">{{ requiredText }}</el-checkbox>
            <el-switch
              v-if="statusRequired && (data._isAdd || data._isEdit) && (node.level === 3 || node.parent.data.id === 24)"
              v-model="data.status"
              :active-value="true"
              :inactive-value="false"
              active-color="#406EFF"
              inactive-color="#ccc"
              active-text="启用"
              inactive-text="禁用"
              style="margin-left: 16px;"/>
            <!-- <el-checkbox v-if="(data._isAdd || data._isEdit) && data.pid.includes('1-7-') && node.parent.level === 2" v-model="data.isRequired" style="margin-left: 16px;">发布链接必填</el-checkbox> -->
            <span class="flex-one"/>
            <div v-if="!data._isEdit && !data._isAdd && !data.showOperate && showOperate" class="setting-btn-container" @click.prevent.stop="() => {}">
              <div v-if="addAuth && ((data.fieldSetting && data.level === 3) || (!data.fieldSetting && node.level < data.level))" class="btn" @click.prevent.stop="toAddSetting(node, data)">添加</div>
              <div v-if="editAuth && ((data.fieldSetting && (data.level === 4 || data.level === 6)) || (!data.fieldSetting && node.level !== 1 && data.canOperate))" class="btn" @click.prevent.stop="toEditSetting(data.name, data, !data._isEdit)">编辑</div>
              <div v-if="delAuth && ((data.fieldSetting && (data.level === 4 || data.level === 6)) || (!data.fieldSetting && node.level !== 1 && data.canOperate))" class="btn" @click.prevent.stop="deleteSetting(node,data)">删除</div>
              <div v-if="data.fieldSetting && data.level === 5" class="btn" @click.prevent.stop="addField(data)">添加字段</div>
            </div>
          </div>
        </el-tree>
      </div>
    </div>
    <div v-else style="font-size: 14px;color: #666;text-align:center;">
      <img :src="emptyImg" style="width: 120px;" class="empty-img" alt="">
      <div style="text-align:center;">暂无数据</div>
    </div>
  </div>
</template>
<script>
import { deleteSetting, editSetting, addSetting } from '@/api/setting';
import { platformList } from '@/api/select';
import ElMessage from '@/utils/message';
import emptyImg from '@/assets/empty-table-data.png';
import { changeColorAlphaVal } from '@/utils/tools';
import { hasRouteAuth } from '@/utils/permission';
import { showModal } from '@/utils/message';
import expend from '@/assets/setting/expend.png';
import expend_active from '@/assets/setting/expend-active.png';
import expend_active_no from '@/assets/setting/expend-active_no.png';

export default {
  components: { },
  props: {
    fieldItems: {
      type: Array,
      default: () => {
        return [];
      }
    },
    draggable: {
      type: Boolean,
      default: false
    },
    showSelectType: { // 是否可以选择字段类型，只有条件筛选的叶子结点才有
      type: Boolean,
      default: false
    },
    // 拖拽时判定目标节点能否被放置。type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
    // Function(draggingNode, dropNode, type)
    allowDrop: {
      type: Function,
      default: null
    },
    // 判断节点能否被拖拽 Function(node)
    allowDrag: {
      type: Function,
      default: null
    },
    defaultExpandedKeys: {
      type: Array,
      default: () => {
        return [];
      }
    },
    showOperate: { // 不显示操作按钮
      type: Boolean,
      default: true
    },
    extentSelect: {
      type: Object,
      default: null
    },
    checkboxRequired: {
      type: Boolean,
      default: false
    },
    lastCheckRequired: {
      type: Boolean,
      default: false
    },
    requiredText: {
      type: String,
      default: ''
    },
    statusRequired: {
      type: Boolean,
      default: false
    },
    addAuth: {
      type: Boolean,
      default: true
    },
    editAuth: {
      type: Boolean,
      default: true
    },
    delAuth: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      emptyImg, expend, expend_active, expend_active_no,
      fieldData: [],
      loading: false,
      addLoading: false,
      optionsTypeList: [
        { value: 0, label: '文本型' },
        { value: 1, label: '时间日期' },
        { value: 2, label: '数值型' },
        { value: 3, label: '部门' }
      ],
      defaultProps: {
        children: 'item',
        label: 'name'
      },
      platformList: [], // 下单平台
      cloneLinkInvoiceType: null,
      customerStatusBg: null
    };
  },
  mounted() {
    platformList().then(res => {
      if (res.code === 200) {
        this.platformList = res.data;
      }
    }).catch(err => {
      console.log(err);
    });
  },
  methods: {
    hasRouteAuth,
    changeColorAlphaVal,
    getData(respetPid) {
      this.$emit('getData', respetPid);
    },
    // 客户管理-客户状态
    isCustomerStatus(node) {
      return node.parent.data.id === 4 && node.parent.data.name === '客户状态';
    },
    // 新增字段
    toAddSetting(node, data) {
      if (!node.expanded) this.$set(node, 'expanded', true);
      if (data.item && data.item.length > 0) {
        const hasAddItem = data.item.some(i => {
          return i._isAdd === true;
        });
        if (hasAddItem) return;
      }
      const newChild = { name: '', _isAdd: true, level: data.fieldSetting ? (data.level + 1) : data.level, item: [], pid: data.pid };
      if (data.fieldSetting) {
        newChild.fieldSetting = true;
      }
      if (data.id === 24) { // 新建银行默认启用
        newChild.status = true;
      }
      // node.level 当前在哪一层
      // data.level 总共有几层
      // 这里只有最后一层才会有 optionsType，所以判断 newChild 的级数是否最后一层
      if (this.showSelectType && (node.level + 1) === data.level) {
        newChild.optionsType = 0;
        newChild.showOptionsType = true;
      }
      if (!data.item) {
        this.$set(data, 'item', []);
      }
      data.item.unshift(newChild);
    },
    cancelAdd(node, data) {
      const parent = node.parent;
      const children = parent.data.item || parent.data;
      const index = children.findIndex(d => d.id === data.id);
      children.splice(index, 1);
    },
    httpAddSetting(node, data) {
      if (data.fieldSetting && data.level === 4) {
        data.name = this.idToName(data.platformId);
      }
      if (!data.name) {
        ElMessage.warning('请输入内容');
        return;
      }
      if (this.isCustomerStatus(node) && !data.color) {
        ElMessage.warning('请选择状态背景色');
        return;
      }
      const root = this.getRoot(node);
      const params = {
        type: root.data.id,
        name: data.name
      };
      if (data.linkInvoiceType) {
        params.linkInvoiceType = data.linkInvoiceType;
      }
      if (data.fieldSetting) {
        params.platformId = data.platformId;
        params.level = data.level;
      }
      if (node.level > 2) {
        params.orderPlatformId = node.parent.data.id;
      }
      // v3.4.7 发布链接是否必填
      params.isRequired = data.isRequired || false;
      if (this.statusRequired) {
        params.status = data.status || false;
      }
      if (this.showSelectType && (data.optionsType || data.optionsType === 0)) {
        params.optionsType = data.optionsType;
      }
      if (this.isCustomerStatus(node)) {
        params.color = data.color;
      }
      this.addLoading = true;
      if (params.name) {
        params.name = params.name.trim();
      }
      addSetting(params).then(res => {
        this.addLoading = false;
        if (res.code === 200) {
          ElMessage.success('新增成功');
          this.$set(data, '_isAdd', false);
          this.$set(data, 'id', res.data);
          this.getData([data.pid]);
        } else {
          ElMessage.success(res.message);
        }
      }).catch(err => {
        this.addLoading = false;
        console.log(err);
      });
    },
    // 新增字段 end
    // 编辑字段
    toEditSetting(name, data, type) {
      if (data.fieldSetting && data.level === 6) {
        this.$emit('editField', data);
      } else {
        this.$set(data, '_isEdit', type);
      }
      if (this.extentSelect && this.extentSelect.key === 'linkInvoiceType') {
        if (type) {
          this.cloneLinkInvoiceType = data.linkInvoiceType;
        } else {
          data.linkInvoiceType = this.cloneLinkInvoiceType;
        }
      }
      if (data.parentId === 4) { // 客户状态
        if (type) {
          this.customerStatusBg = data.color;
        } else {
          data.color = this.customerStatusBg;
        }
      }
      if (name !== '') {
        this.$set(data, 'editName', name);
      }
      if (type && this.showSelectType) {
        this.$set(data, 'editOptionsType', data.optionsType || 0);
      }
    },
    extentSelectChange(node, data) {
      if (!data._isAdd && !data._isEdit) {
        data.editName = data.name;
        this.httpEditSetting(node, data, true);
      }
    },
    httpEditSetting(node, data, mute = false) {
      if (!data.editName) {
        ElMessage.warning('请输入内容');
        return;
      }
      if (this.isCustomerStatus(node) && !data.color) {
        ElMessage.warning('请选择状态背景色');
        return;
      }
      if (!mute) this.addLoading = true;
      const root = this.getRoot(node);
      const params = {
        type: root.data.id,
        id: data.id,
        name: data.editName || data.name
      };
      if (data.linkInvoiceType) {
        params.linkInvoiceType = data.linkInvoiceType;
      }
      if (data.fieldSetting) {
        params.platformId = data.platformId;
        params.level = data.level;
      }
      if (data.fieldSetting && data.level === 4) {
        params.name = this.idToName(data.platformId);
      }
      if (this.showSelectType) {
        params.optionsType = data.editOptionsType || 0;
      }
      if (node.level > 2) {
        params.orderPlatformId = node.parent.data.id;
      }
      /* if (data.pid.includes('1-7-') && node.parent.level === 2) { // v3.4.7 发布链接是否必填
        params.isRequired = data.isRequired;
      } */
      if (this.checkboxRequired || this.lastCheckRequired) { // v3.4.9 纳税人信息是否必填
        params.isRequired = data.isRequired;
      }
      if (this.statusRequired) {
        params.status = data.status || false;
      }
      if (params.name) {
        params.name = params.name.trim();
      }
      if (this.isCustomerStatus(node)) {
        params.color = data.color;
      }
      this.cloneLinkInvoiceType = null;
      editSetting(params).then(res => {
        this.addLoading = false;
        if (res.code === 200) {
          ElMessage.success('修改成功');
          this.$set(data, '_isEdit', false);
          this.$set(data, 'name', params.name);
          this.getData([node.parent.data.pid]);
        } else {
          ElMessage.success(res.message);
        }
      }).catch(err => {
        this.addLoading = false;
        console.log(err);
      });
    },
    // 编辑字段 end
    deleteSetting(node, data) {
      showModal('是否确认删除？', '', {
        center: true,
        showClose: true
      }).then(() => {
        const root = this.getRoot(node);
        const params = {
          type: root.data.id,
          id: data.id,
          name: data.name
        };
        if (node.level > 2) {
          params.orderPlatformId = node.parent.data.id;
        }
        if (!data._isAdd) {
          deleteSetting(params).then(res => {
            if (res.code === 200) {
              ElMessage.success('删除成功');
              // const parent = node.parent;
              // const children = parent.data.item || parent.data;
              // const index = children.findIndex(d => d.id === data.id);
              // children.splice(index, 1);
              this.getData([node.parent.data.pid]);
            } else {
              ElMessage.error(res.message);
            }
          }).catch(err => {
            console.error(err);
          });
        }
      });
    },
    getRoot(node) {
      if (!node) return null;
      if (node.level === 1) {
        return node;
      }
      return this.getRoot(node.parent);
    },
    // 拖动
    handleDragStart(node, ev) {
      this.$emit('node-drag-start', node, ev);
    },
    handleDragEnter(draggingNode, dropNode, ev) {
      this.$emit('node-drag-enter', draggingNode, dropNode, ev);
    },
    handleDragLeave(draggingNode, dropNode, ev) {
      this.$emit('node-drag-leave', draggingNode, dropNode, ev);
    },
    handleDragOver(draggingNode, dropNode, ev) {
      this.$emit('node-drag-over', draggingNode, dropNode, ev);
    },
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      this.$emit('node-drag-end', draggingNode, dropNode, dropType, ev);
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      this.$emit('node-drop', draggingNode, dropNode, dropType, ev);
    },
    addField(data) {
      this.$emit('addField', data);
    },
    idToName(id) {
      const res = this.platformList.find(item => {
        if (item.id === id) {
          return item;
        }
      });
      return res.value;
    }
  }
};
</script>
<style lang="scss" scoped>
.setting-main {
  & ::v-deep {
    .el-tree {
      .el-tree-node {
        position: relative;
      }
      & > .el-tree-node {
        padding: 15px 1px;
        border-bottom: 1px solid #EBEEFD;
        position: relative;
        & > .el-tree-node__content {
          margin: 0;
        }
        &:nth-last-child(2) {
          border-bottom: none;
        }
      }
    }
    .el-tree-node__content {
      background-color: #fff;
      height: 32px;
      margin-top: 10px;
      &:hover {
        background-color: #fff;
      }
      &:last-child {
        margin-bottom: 10px;
      }
    }
    .el-tree-node__expand-icon {
      // display: none;
      height: 100%;
      visibility: hidden;
      padding: 0;
      position: absolute;
      left: -12px;
      top: 0px;
      transform: rotate(0deg) !important;
    }

    .custom-tree-node {
      @include flexStyle($align:center, $flexOne: 1);
      width: 100%;
      font-size: 14px;
      .setting-btn-container {
        margin-left: 20px;
        display: flex;
        width: 114px;
        align-items: center;
        .btn {
          margin-left: 10px;
          color: #406eff;
          cursor: pointer;
        }
      }
      .is-draggable {
        cursor: move;
      }
      .tree-main {
        font-size: 14px;
        font-family:PingFangSC-Regular,PingFang SC;
        font-weight:400;
        color:rgba(102,102,102,1);
        line-height:16px;
        // overflow-x: hidden;
        text-overflow: ellipsis;
        .el-icon-check {
          font-size: 15px;
          color: #406EFF;
        }
        .el-input__icon {
          width: 40px;
        }
        .el-icon-close {
          font-size: 15px;
        }
        & ::v-deep {
          .el-input {
            .el-input__inner {
              border-color: #DDDDDD;
            }
          }
          .el-input--suffix .el-input__inner {
            padding-right: 48px;
          }
        }
        .input {
          width: 240px;
          margin-right: 10px;
        }
      }
      .customer-status-label {
        display: inline-block;
        color: #fff;
        padding: 2px 12px;
        border-radius: 999px;
      }
    }
    .el-switch__core{
      width: 60px !important;
      cursor: pointer;
    }
    .el-switch__label {
      span {
        cursor: pointer;
      }
    }
    .el-switch__label--left {
      position: absolute;
      left: 24px;
      color: #fff;
      z-index: -1111;
      cursor: default;
      user-select: none;
    }
    .el-switch__label--right {
      position: absolute;
      right: 24px;
      color: #fff;
      z-index: -1111;
      cursor: default;
      user-select: none;
    }
    .el-switch__label--right.is-active {
      z-index: 1111;
      color: #fff!important;
    }
    .el-switch__label--left.is-active {
      z-index: 1111;
      color: #9c9c9c!important;
    }
    .nopointer {
      .el-switch__core {
        cursor: default;
      }
      .el-switch__label {
        span {
          cursor: default;
        }
      }
    }
  }
}
.expend-icon {
  @include flexStyle($align:center, $justify:center);
  width: 16px;
  height: 16px;
}
.expend-btn {
  @extend .expend-icon;
  margin-right: 20px;
}
.tree-main{
  &::v-deep{
    .el-input--suffix .el-input__inner{
      padding-right: 45px;
    }
  }
}
.select-type {
  display: flex;
  align-items: center;
}
.width140 {
  width: 140px;
}
.tag-module-select {
  min-width: 150px;
  &::v-deep {
    .el-tag {
      @include flexStyle($align: center);
      span {
        max-width: 80px;
        display: inline-block;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
    .el-tag.el-tag--info {
      color: #406EFF !important;
      background-color: #EFF3FB !important;
    }
  }
}
</style>
